package com.renne.email.service;

import com.renne.common.core.text.Convert;
import com.renne.email.domain.MailSenderConfigVo;
import com.sun.mail.util.MailSSLSocketFactory;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.List;
import java.util.Properties;

/**
 * 自定义邮件推送组件
 */
@Component
public class MailPushService {

    private final Logger logger = LoggerFactory.getLogger(MailPushService.class);

    @Autowired
    private IMailSenderConfigService mailSenderConfigService;


    /**
     * 发送邮件（简单模式）
     *
     * @param toEmail
     * @param subject
     * @param content
     */
    public void sendMail(String toEmail, String subject, String content) throws GeneralSecurityException, MessagingException, UnsupportedEncodingException {

        MailSenderConfigVo config = mailSenderConfigService.getEnabledMailSenderConfigVo();

        final Properties props = new Properties();
        //服务器
        props.put("mail.smtp.host", config.getHost());
        //端口
        props.put("mail.smtp.port", config.getPort());
        //协议
        props.setProperty("mail.transport.protocol", config.getProtocol());
        //用户名
        props.put("mail.user", config.getUsername());
        //密码
        props.put("mail.password", config.getAuthorizationCode());
        //使用smtp身份验证
        props.put("mail.smtp.auth", "true");

        //开启安全协议
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.smtp.ssl.socketFactory", sf);
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(props.getProperty("mail.user"),
                        props.getProperty("mail.password"));
            }
        };

        Session session = Session.getDefaultInstance(props, authenticator);
        session.setDebug(true);
        MimeMessage mimeMessage = new MimeMessage(session);
        mimeMessage.setFrom(new InternetAddress(config.getEmail(), MimeUtility.encodeText(config.getUsername())));
        mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toEmail));
        mimeMessage.setSubject(subject);
        mimeMessage.setContent(content, "text/html;charset=UTF-8");

        //保存信息
        mimeMessage.saveChanges();
        //发送消息
        Transport.send(mimeMessage);
        logger.info("简单邮件已经发送。");

    }


    /**
     * 发送邮件（复杂模式）
     *
     * @param toEmail    接受者邮箱
     * @param subject    主题
     * @param sendHtml   内容
     * @param attachment 附件
     */
    public void sendMail(String toEmail, String subject, String sendHtml, File attachment) throws GeneralSecurityException, UnsupportedEncodingException, MessagingException {
        MailSenderConfigVo config = mailSenderConfigService.getEnabledMailSenderConfigVo();
        //设置了附件名过长问题
        System.setProperty("mail.mime.splitlongparameters", "false");

        final Properties props = new Properties();
        //服务器
        props.put("mail.smtp.host", config.getHost());
        //端口
        props.put("mail.smtp.port", config.getPort());
        //协议
        props.setProperty("mail.transport.protocol", config.getProtocol());
        //用户名
        props.put("mail.user", config.getUsername());
        //密码
        props.put("mail.password", config.getAuthorizationCode());
        //使用smtp身份验证
        props.put("mail.smtp.auth", "true");

        //开启安全协议
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.smtp.ssl.socketFactory", sf);
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(props.getProperty("mail.user"),
                        props.getProperty("mail.password"));
            }
        };

        Session session = Session.getDefaultInstance(props, authenticator);
        session.setDebug(true);
        MimeMessage mimeMessage = new MimeMessage(session);
        // 发送者邮箱
        mimeMessage.setFrom(new InternetAddress(config.getEmail(), MimeUtility.encodeText(config.getUsername())));
        // 接受者邮箱
        mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toEmail));
        // 邮件主题
        mimeMessage.setSubject(subject);
        // 定义邮件内容
        Multipart multipart = new MimeMultipart();

        // 添加邮件正文
        BodyPart contentPart = new MimeBodyPart();
        contentPart.setContent(sendHtml, "text/html;charset=UTF-8");
        multipart.addBodyPart(contentPart);

        // 添加附件
        if (attachment != null) {
            BodyPart attachmentBodyPart = new MimeBodyPart();
            // MimeUtility.encodeWord可以避免文件名乱码
            FileDataSource fds = new FileDataSource(attachment);
            attachmentBodyPart.setDataHandler(new DataHandler(fds));
            attachmentBodyPart.setFileName(MimeUtility.encodeText(fds.getName()));
            multipart.addBodyPart(attachmentBodyPart);
        }

        // 将multipart对象放到message中
        mimeMessage.setContent(multipart);

        //保存信息
        mimeMessage.saveChanges();
        //发送消息
        Transport.send(mimeMessage);
        logger.info("邮件已经发送。");

    }


    /**
     * 发送邮件（复杂模式）
     *
     * @param toEmail        接受者邮箱
     * @param copyEmails     抄送人邮箱
     * @param subject        主题
     * @param sendHtml       内容
     * @param attachmentList 附件集合
     */
    public void sendMail(String toEmail, String copyEmails, String subject, String sendHtml, List<File> attachmentList) throws MessagingException, UnsupportedEncodingException, GeneralSecurityException {

        MailSenderConfigVo config = mailSenderConfigService.getEnabledMailSenderConfigVo();
        //设置了附件名过长问题
        System.setProperty("mail.mime.splitlongparameters", "false");

        final Properties props = new Properties();
        //服务器
        props.put("mail.smtp.host", config.getHost());
        //端口
        props.put("mail.smtp.port", config.getPort());
        //协议
        props.setProperty("mail.transport.protocol", config.getProtocol());
        //用户名
        props.put("mail.user", config.getEmail());
        //密码
        props.put("mail.password", config.getAuthorizationCode());
        //使用smtp身份验证
        props.put("mail.smtp.auth", "true");

        //开启安全协议
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.smtp.ssl.socketFactory", sf);
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(props.getProperty("mail.user"),
                        props.getProperty("mail.password"));
            }
        };

        Session session = Session.getDefaultInstance(props, authenticator);
        session.setDebug(true);
        MimeMessage mimeMessage = new MimeMessage(session);
        // 发送者邮箱
        mimeMessage.setFrom(new InternetAddress(config.getEmail(), MimeUtility.encodeText(config.getUsername())));
        // 接受者邮箱
        mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toEmail));
        // 设置多个抄送人
        String[] copyEmailArr = null != copyEmails ? Convert.toStrArray(copyEmails) : new String[0];
        if (ArrayUtils.isNotEmpty(copyEmailArr)) {
            for (String copyEmail : copyEmailArr) {
                mimeMessage.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(copyEmail));
            }
        }
        // 邮件主题
        mimeMessage.setSubject(subject);
        // 定义邮件内容
        Multipart multipart = new MimeMultipart();

        // 添加邮件正文
        BodyPart contentPart = new MimeBodyPart();
        contentPart.setContent(sendHtml, "text/html;charset=UTF-8");
        multipart.addBodyPart(contentPart);

        // 添加附件
        if (attachmentList != null) {
            for (File attachment : attachmentList) {
                BodyPart attachmentBodyPart = new MimeBodyPart();
                FileDataSource fds = new FileDataSource(attachment);
                attachmentBodyPart.setDataHandler(new DataHandler(fds));
                attachmentBodyPart.setFileName(MimeUtility.encodeText(fds.getName()));
                multipart.addBodyPart(attachmentBodyPart);
            }
        }
        // 将multipart对象放到message中
        mimeMessage.setContent(multipart);

        //保存信息
        mimeMessage.saveChanges();
        //发送消息
        Transport.send(mimeMessage);
        logger.info("邮件已经发送。");

    }
}
